home *** CD-ROM | disk | FTP | other *** search
- /*********************************************************************************************************************************
- *
- * ElementADT.c
- *
- * Functions related to the Element Abstract Data Type
- *
- * Theory of Operation:
- *
- * The public functions allocate and deallocate memory for the in-memory storage of
- * the data necessary to represent an element. Public functions call private (file static)
- * functions to maintain a linked list of elements.
- *
- * The public functions also provide an iterator service that can be used by the client
- * to retrieve element references from the linked list.
- *
- * The public function ElementError can be used to retrieve any potential error code
- * generated by the most recent public function called by the client.
- *
- * IMPORTANT DEFINITIONS:
- * Element List - a doubly-linked list consisting of a head node plus zero or more elements
- * - elements in a list are completely maintained by this code
- * - destroying an list destroys all its elements.
- * - an element can be removed from its list, and is then called an orphan
- * - an element has a subelement list, which is used to implement groups
- *
- * Element Chain - a doubly-linked list consisting of one or more elements, called orphans
- * - a chain is not connected to a head node nor to any Element List.
- * - the user is responsible for destroying orphaned elements
- * by calling FreeOrphanChain(headOfChain);
- *
- *
- *********************************************************************************************************************************/
- #include <string.h>
-
- #include "Structs.h"
-
- #include "ElementADT.h"
- #include "ElementHelpers.h"
-
- #include "Assertion.h"
-
- #define kLockElementReferences false
-
- // ------------------------------------------------------------------------------------------------
-
- static OSErr fgError = noErr;
- static Rect fgEmptyRect = {0, 0, 0, 0};
- static Point fgEmptyPoint = {0, 0};
- static unsigned long fgElementCount = 0;
- static unsigned long fgElementNumber = 0;
-
- // ------------------------------------------------------------------------------------------------
-
- static OSErr CreateElementData (ElementReference element, ElementType type);
- static OSErr CloneElementData (ElementReference element, ElementReference clone);
- static void FreeElementData (ElementReference element);
- static void FreeElement (ElementReference element);
- static void Insert (ElementList list, ElementReference element);
- static void Remove (ElementReference element);
- static void Link (ElementReference previous, ElementReference next);
-
- static Boolean ElementListIsValid (ElementList list);
- static Boolean ElementIsValid (ElementReference element);
- static Boolean ElementIsOrphan (ElementReference element, Boolean warnUser);
- static ElementReference GetLastElementInChain (ElementReference firstElement);
-
- static Handle CloneHandle (Handle original);
-
- /*****************************************************************************
- *
- * ElementError PUBLIC
- *
- * Retrieves the error generated by the last element-related function called
- * by the client. If no error occured, the result will be zero (noErr).
- *
- *****************************************************************************/
- OSErr ElementError(void)
- {
- return fgError;
- }
-
-
- /*****************************************************************************
- *
- * CreateElementList PUBLIC
- *
- * Call to create a new element list for use by an ad or sub-element list.
- * CreateElementList allocates the list header node and returns it to the
- * caller.
- *
- *****************************************************************************/
- ElementList CreateElementList(void)
- {
- ElementList list;
-
-
- list = (ElementList) NewHandleClear(sizeof(ElementRecord));
- fgError = MemError();
-
- if ((list == nil) && (fgError == noErr))
- fgError = memFullErr;
-
- if (fgError == noErr)
- {
- fgElementCount++;
-
- if (kLockElementReferences)
- HLockHi((Handle) list);
-
- (**list).structID = kElementListID;
- }
- else if (list != nil)
- {
- DisposeHandle((Handle)list);
- list = nil;
- }
-
-
- return list;
- }
-
-
- /*****************************************************************************
- *
- * CreateElement PUBLIC
- *
- * Called to create a new element structure in memory. This function completely
- * initializes the element structure including the creation of an empty
- * sub-element list.
- *
- *****************************************************************************/
- ElementReference CreateElement(ElementList list, ElementType type)
- {
- ElementReference element;
- ElementList sublist;
-
-
- element = (ElementReference) NewHandleClear(sizeof (ElementRecord));
- fgError = MemError();
-
- if ((element == nil) && (fgError == noErr))
- fgError = memFullErr;
-
-
- if (fgError == noErr)
- {
- fgElementCount++;
-
- if (kLockElementReferences == true)
- HLockHi((Handle) element);
-
- (**element).structID = kElementRecordID;
- (**element).elementNumber = ++fgElementNumber;
-
- Insert(list, element);
-
- fgError = CreateElementData(element, type);
-
- if (fgError == noErr)
- {
- sublist = CreateElementList();
- if (fgError == noErr)
- (**element).subElementList = sublist;
- }
-
- if (fgError != noErr)
- {
- DestroyElement(element);
- element = nil;
- }
- }
- else if (element != nil)
- {
- DisposeHandle((Handle)element);
- element = nil;
- }
-
- return element;
- }
-
-
- /*****************************************************************************
- *
- * DestroyElementList PUBLIC
- *
- * Called during ad destruction to destroy the entire element list, or during
- * element destruction to destroy the sub-element list.
- *
- * DestroyElementList is a "deep" destory: it will destroy all dynamicData memory
- * associated with every element in the list.
- *
- * • NOTE: THE SPECIFIED ELEMENT LIST IS INVALID AFTER THIS FUNCTION RETURNS
- *
- *****************************************************************************/
- void DestroyElementList(ElementList list)
- {
- ElementReference element;
-
-
- if (ElementListIsValid(list))
- {
- element = GetFirstElement(list);
- while (element != nil)
- {
- DestroyElement(element);
- element = GetFirstElement(list);
- }
-
- DisposeHandle((Handle)list);
- fgElementCount--;
- }
- }
-
-
- /*****************************************************************************
- *
- * DestroyElementRange PUBLIC
- *
- * Releases all of the dynamicData memory associated with a range of elements
- * then releases the elements themselves. This includes the destruction of the
- * any sub-element lists and all of their dynamicData memory.
- *
- * If endElement is nil, then all elements from beginElement to the end of the
- * list will be destroyed.
- *
- * • NOTE: This can not be used on element chains because DestroyElement()
- * performs link maintenance on the element list. If the caller orphans
- * elements to create a chain (of one or more links), then the caller
- * should use FreeOrphanChain() instead of DestroyElementRange().
- *
- *****************************************************************************/
- void DestroyElementRange(ElementReference beginElement, ElementReference endElementOrNil)
- {
- ElementReference element = beginElement;
- ElementReference nextElement = nil;
-
-
- while (element != nil)
- {
- nextElement = GetNextElement(element);
-
- if (element != nil)
- DestroyElement(element);
-
- if (element == endElementOrNil)
- break;
-
- element = nextElement;
- }
- }
-
-
- /*****************************************************************************
- *
- * DestroyElement PUBLIC
- *
- * Releases all of the dynamicData memory associated with the specified element and
- * then releases the element itself . This includes the destruction of the
- * element’s sub-element list and all of its dynamicData memory.
- *
- * • NOTE: DestroyElement can NOT be used on orphans because of link maintenence!
- *
- *****************************************************************************/
- void DestroyElement(ElementReference element)
- {
- ElementList sublist;
-
-
- if (ElementIsValid(element))
- {
- Remove(element);
-
- sublist = GetElementSubElementList(element);
- if (sublist != nil)
- DestroyElementList(sublist);
-
- FreeElementData(element);
- FreeElement(element);
- }
- }
-
-
- /*****************************************************************************
- *
- * CountElements PUBLIC
- *
- * Returns the number of elements contained in a specified element list.
- *
- * • NOTE: This does NOT include the count of any elements that may or may not
- * be in sub-element lists.
- *
- *****************************************************************************/
- short CountElements(ElementList list)
- {
- ElementReference element;
- short count;
-
-
- count = 0;
-
- if (ElementListIsValid(list))
- for (element = GetFirstElement(list); element != nil; element = GetNextElement(element))
- count++;
-
- return count;
- }
-
-
- /*****************************************************************************
- *
- * CountElementAllocations PUBLIC
- *
- * Returns the number of elements allocation
- *
- *****************************************************************************/
- unsigned long CountElementAllocations(void)
- {
- return fgElementCount;
- }
-
-
- /*****************************************************************************
- *
- * GetFirstElement PUBLIC
- *
- * Retrieves the first element in an element list (skips the list head).
- * If the list is empty, NIL is returned.
- *
- *****************************************************************************/
- ElementReference GetFirstElement(ElementList list)
- {
- return ElementListIsValid(list) ? (**list).next : nil;
- }
-
-
-
- /*****************************************************************************
- *
- * GetLastElement PUBLIC
- *
- * Find last element in list
- *
- *****************************************************************************/
- ElementReference GetLastElement(ElementList list)
- {
- ElementReference element;
-
-
- element = GetFirstElement(list); // find the last element in the list
- if (element != nil) // while there are more elements in list
- while (GetNextElement(element) != nil) // move forwards in the list
- element = GetNextElement(element);
-
- return element;
- }
-
-
- /*****************************************************************************
- *
- * GetNextElement PUBLIC
- *
- * Returns the next element reference after a specified element
- *
- *****************************************************************************/
- ElementReference GetNextElement(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).next : nil;
- }
-
-
- /*****************************************************************************
- *
- * GetPreviousElement PUBLIC
- *
- * Returns the element previous to a specified element, but ignores the list
- * header. If the specified element is the first "valid" element in the list,
- * then nil is returned.
- *
- *****************************************************************************/
- ElementReference GetPreviousElement(ElementReference element)
- {
- ElementReference previous;
-
- previous = nil;
-
- if (ElementIsValid(element))
- {
- previous = (**element).previous;
- if ((**previous).structID == kElementListID)
- previous = nil;
- }
-
- return previous;
- }
-
-
- /*****************************************************************************
- *
- * GetElementList PUBLIC
- *
- * Returns the element list reference that owns an element. If the element is
- * an orphan (or in an orphaned element chain), nil will be returned.
- *
- *****************************************************************************/
- ElementList GetElementList(ElementReference element)
- {
- ElementList list;
-
- list = nil;
-
- if (ElementIsValid(element))
- {
- while ((element != nil) && ((**element).structID != kElementListID)) // if the element is not the head of the list
- element = (**element).previous; // then get the previous element and try again
-
- list = element;
- }
-
- return list;
- }
-
- /*****************************************************************************
- *
- * GetSubElementList
- *
- *****************************************************************************/
- ElementList GetSubElementList(ElementReference element)
- {
- return GetElementSubElementList(element);
- }
-
- /*****************************************************************************
- *
- * CloneElementList PUBLIC
- *
- * Creates a new element list and populates it with the contents of the specified
- * source element list. Any attached sub-element lists are also cloned. Note that
- * static items such as attached TIFF images are cloned using the Static Item ADT.
- *
- * The two lists will have identical element numbers (and owner numbers for
- * clipping paths).
- *
- *****************************************************************************/
- ElementList CloneElementList(ElementList sourceList)
- {
- OSErr error;
- ElementList destinationList;
- ElementReference iterator;
- ElementReference clone;
-
- error = nilHandleErr;
- destinationList = nil;
-
- if (ElementListIsValid(sourceList))
- {
- destinationList = CreateElementList(); // create the new clone list
- error = ElementError(); // did creating it fail?
-
- if (destinationList != nil)
- {
- for (iterator = GetFirstElement(sourceList); iterator != nil; iterator = GetNextElement(iterator))
- {
- clone = CloneElement(iterator); // clone the element
- error = ElementError(); // did it fail?
-
- if (clone != nil) // if not, insert it in the clone list
- { // and synchronize the element numbers
- Insert(destinationList, clone); // also synchronize clipping paths (if we are supposed to!)
- }
- else // otherwise we need to destroy what
- { // we've already cloned and then
- DestroyElementList(destinationList); // return a nil result (and an error
- destinationList = nil; // via ElementError() to the caller).
- break;
- }
- }
-
-
- if (destinationList != nil)
- {
- (**destinationList).elementNumber = (**sourceList).elementNumber;
- }
- }
- }
-
- fgError = error; // be sure to (re)populate this!
- return destinationList; // return resulting list (may be nil!)
- }
-
-
- /*****************************************************************************
- *
- * CloneElement PUBLIC
- *
- * Creates a new element and populates it with the contents of the specified
- * source element including any sub-elements.
- *
- * The cloned element is an orphan and will need to be adopted into a list
- *
- *****************************************************************************/
- ElementReference CloneElement(ElementReference element)
- {
- ElementReference clone;
- ElementList owningList;
- OSErr error;
-
- error = nilHandleErr;
- clone = nil;
-
- if (ElementIsValid(element))
- {
- owningList = GetElementList(element);
-
- if (ElementListIsValid(owningList))
- {
- clone = CreateElement(owningList, GetElementType(element)); // try to create the clone element
- error = ElementError();
-
- if (error == noErr)
- {
- OrphanElement(clone); // orphan it
- error = CloneElementData(element, clone); // and copy the original’s data
- }
-
- if (error == noErr) // if there was not an error up above
- { // then clone sub-element list
- DisposeHandle((Handle)((**clone).subElementList)); // dispose of existing header
- fgElementCount--;
- (**clone).subElementList = CloneElementList((**element).subElementList); // did this fail?
- error = ElementError();
- }
-
- if (error != noErr) // did something fail?
- { // if so release this puppy--we’ve failed!
- FreeOrphanChain(clone); // and zero out the return result
- clone = nil;
- }
- }
- }
-
- fgError = error; // be sure to (re)populate this correctly
- return clone; // and return this guy to the caller
- }
-
- /*****************************************************************************
- *
- * OrphanElement PUBLIC
- *
- * OrphanElement extracts an element from a list. Only the specified element
- * is extracted--the linkages to the next and previous elements in the list
- * are adjusted. Of course if the element has a sub-element list attached to
- * it, the list remains with the orphaned element.
- *
- * When an element is orphaned, the caller takes responsibility for the
- * element - especially its destruction when they are done with it.
- *
- * An orphand can be "adopted" using AdoptOrphan or either of the
- * AdoptOrphanInsertingXXXElement functions. Once this happens, the element is
- * no longer and orphan and the list maintenance code regains responsibilty
- * for managing the element.
- *
- *****************************************************************************/
- void OrphanElement(ElementReference element)
- {
- if (ElementIsValid(element))
- if (ElementIsOrphan(element, false) == false)
- Remove(element);
- }
-
-
- /*****************************************************************************
- *
- * OrphanElementRange PUBLIC
- *
- * Like DestroyElementRange, OrphanElementRange operates on a range of elements
- * specified by an element to begin with and an element to end with. Essentially,
- * OrphanElementRange extracts an range of elements by adjusting the links of the
- * neighboring elements.
- *
- * If endElement is nil, then all elements from beginElement to the end of the
- * list will be orphaned.
- *
- * An linked-list of orphaned elements is called a "chain."
- * A "chain" is not an "element list" because it does not have a head node
- * The caller takes responsibility for the elements in the chain
- * - especially their destruction when they are done with them.
- *
- * An chain can be "adopted" using AdoptOrphan or
- * either of the AdoptOrphanInsertingXXXElement functions. Once this happens, the chain becomes
- * part of a valid list and is no longer orphaned and the list maintenance code
- * regains responsibilty for managing the elements.
- *
- *****************************************************************************/
- void OrphanElementRange(ElementReference beginElement, ElementReference endElementOrNil)
- {
- ElementReference previous = (**beginElement).previous;
- ElementReference next = endElementOrNil;
-
- if (endElementOrNil != nil)
- {
- next = GetNextElement(endElementOrNil);
- (**endElementOrNil).next = nil; // the end of the chain
- }
-
- Link(previous, next);
- (**beginElement).previous = nil; // the beginning of the chain
- }
-
-
- /*****************************************************************************
- *
- * AdoptOrphan PUBLIC
- *
- * AdoptOrphan always appends the specified element to the end of the
- * specified list.
- * This function is quite useful in moving an existing element from one list
- * to another.
- *
- * NOTE: The specified element may be the first element in a "chain" -
- * (such as the element range resulting from a call to
- * OrphanElementRange). Since this function only deals with the
- * links between the last element in a ElementList and the element specified,
- * this is not a problem.
- *
- *****************************************************************************/
- void AdoptOrphan(ElementList list, ElementReference orphan)
- {
- if (ElementIsOrphan(orphan, true))
- Insert(list, orphan);
- }
-
-
- /*****************************************************************************
- *
- * AdoptOrphanInsertingBeforeElement PUBLIC
- *
- * Inserts the specified orphan or chain before the specified element.
- * To insert an element at the end of an element list use AdoptOrphan.
- * See also AdoptOrphanInsertingAfterElement().
- *
- * NOTE: The orphan may be the first element in a chain, in which case the
- * entire chain is adopted.
- *
- * SAMPLE USAGE:
- *
- * element = GetFirstElement(someList);
- * orphan = CloneElement(element);
- * AdoptOrphanInsertingBeforeElement(orphan, element);
- *
- *****************************************************************************/
- void AdoptOrphanInsertingBeforeElement(ElementReference orphan, ElementReference element)
- {
- ElementReference previous;
- ElementReference last;
- ElementList list;
-
-
- if (ElementIsOrphan(orphan, true))
- {
- list = GetElementList(element);
- previous = (**element).previous;
- last = GetLastElementInChain(orphan);
-
- Link(previous, orphan);
- Link(last, element);
- }
- }
-
-
- /*****************************************************************************
- *
- * AdoptOrphanInsertingAfterElement PUBLIC
- *
- * Inserts the specified orphan or chain after the specified element.
- * To insert an element at the end of an element list use AdoptOrphan.
- * See also AdoptOrphanInsertingBeforeElement().
- *
- * NOTE: The orphan may be the first element in a chain, in which case the
- * entire chain is adopted.
- *
- * SAMPLE USAGE:
- *
- * element = GetFirstElement(list);
- * orphan = CloneElement(element);
- * AdoptOrphanInsertingAfterElement(orphan, element);
- *
- *****************************************************************************/
- void AdoptOrphanInsertingAfterElement(ElementReference orphan, ElementReference element)
- {
- ElementReference next;
- ElementReference last;
- ElementList list;
-
-
- if (ElementIsOrphan(orphan, true))
- {
- list = GetElementList(element);
- next = GetNextElement(element);
- last = GetLastElementInChain(orphan);
-
- Link(element, orphan);
- Link(last, next);
- }
- }
-
-
- /*****************************************************************************
- *
- * FreeOrphanChain PUBLIC
- *
- * Dispose of the elements in an orphan chain
- *
- *****************************************************************************/
- void FreeOrphanChain(ElementReference headOfChain)
- {
- ElementReference orphan = headOfChain;
- ElementReference next = nil;
- ElementList sublist;
-
-
- if (ElementIsOrphan(headOfChain, true))
- while (orphan != nil)
- {
- next = GetNextElement(orphan);
-
- sublist = GetElementSubElementList(orphan);
- if (sublist != nil)
- DestroyElementList(sublist);
-
- FreeElementData(orphan);
- FreeElement(orphan);
-
- orphan = next;
- }
- }
-
-
- /*****************************************************************************
- *
- * CreateElementData PRIVATE
- *
- * Populate a newly created element with default data
- *
- * Variables not assigned here will have zero values because new elements
- * are created via NewHandleClear() which zeroes everything out.
- *
- * • NOTE: This function does NOT allocate the element’s sub-element list
- *
- *****************************************************************************/
- static OSErr CreateElementData(ElementReference element, ElementType type)
- {
- OSErr error = noErr;
-
- PopulateElementWithDefaultData(element);
- SetElementType(element, type);
-
- return error;
- }
-
-
- /*****************************************************************************
- *
- * CloneElementData PRIVATE
- *
- * Copy all static element data from one to another.
- *
- * If this function fails it is the responsibility of the caller to release
- * any of the memory allocated (usually via a call to FreeOrphanChain())
- *
- * • NOTE: This function does NOT copy the element’s sub-element list
- *
- *****************************************************************************/
- static OSErr CloneElementData(ElementReference element, ElementReference clone)
- {
- PolyHandle polygon;
-
- SetElementBoundingBox (clone, GetElementBoundingBox(element));
-
- SetElementStrokePenHeight (clone, GetElementStrokePenHeight(element));
- SetElementStrokePenWidth (clone, GetElementStrokePenWidth(element));
-
- SetElementStrokeColor (clone, GetElementStrokeColor(element));
- SetElementFillColor (clone, GetElementFillColor(element));
-
- SetElementRoundRectOvalSize (clone, GetElementRoundRectOvalSize(element));
- SetElementLineBeginPoint (clone, GetElementLineBeginPoint(element));
- SetElementLineEndPoint (clone, GetElementLineEndPoint(element));
-
- polygon = GetElementPolygon(element); // do not need to copy the transformed polygon because it will get
- if (polygon != nil) // created in SetElementPolygon
- SetElementPolygon(clone, (PolyHandle)CloneHandle((Handle)polygon));
-
- return noErr;
- }
-
- /*****************************************************************************
- *
- * FreeElementData PRIVATE
- *
- * Dispose of all dynamic memory allocated and stored inside this element.
- *
- * • NOTE: This function does NOT release the element’s sub-element list
- *
- *****************************************************************************/
- static void FreeElementData(ElementReference element)
- {
- SetElementPolygon(element, nil);
- }
-
- /*****************************************************************************
- *
- * FreeElement PRIVATE
- *
- * Dispose of the element memory
- *
- *****************************************************************************/
- static void FreeElement(ElementReference element)
- {
- DisposeHandle((Handle)element);
- fgElementCount--;
- }
-
- /*****************************************************************************
- *
- * Insert PRIVATE
- *
- * Insert an element into a list, by appending the element to the
- * end of the list
- *
- *****************************************************************************/
- static void Insert(ElementList list, ElementReference elementToInsert)
- {
- ElementReference element;
-
-
- if (GetFirstElement(list) == nil)
- {
- (**list).next = elementToInsert;
- (**elementToInsert).previous = list;
- }
- else
- {
- element = GetLastElement(list);
- (**element).next = elementToInsert;
- (**elementToInsert).previous = element;
- }
- }
-
-
- /*****************************************************************************
- *
- * Remove PRIVATE
- *
- * Remove an element from the list
- *
- *****************************************************************************/
- static void Remove(ElementReference element)
- {
- ElementReference previous = (**element).previous;
- ElementReference next = (**element).next;
-
- Link(previous, next);
-
- (**element).previous = nil;
- (**element).next = nil;
-
- }
-
-
- /*****************************************************************************
- *
- * Link PRIVATE
- *
- * Establish a 2-way link between two elements
- *
- * The second element CAN BE nil.
- *
- *****************************************************************************/
- static void Link(ElementReference previous, ElementReference next)
- {
- (**previous).next = next;
-
- if (next != nil)
- (**next).previous = previous;
- }
-
-
- /*****************************************************************************
- *
- * ElementListIsValid PRIVATE
- *
- * returns true if specified element is valid. This is useful for debugging.
- *
- *****************************************************************************/
- static Boolean ElementListIsValid(ElementList list)
- {
- ElementReference head = (ElementReference)list;
- Boolean isValid = (head != nil && ((**head).structID == kElementListID));
-
- Assert(isValid, "ELEMENT ADT: An invalid element list has been detected.");
-
- return isValid;
- }
-
-
- /*****************************************************************************
- *
- * ElementIsValid PRIVATE
- *
- * returns true if specified element is valid. This is useful for debugging.
- *
- *****************************************************************************/
- static Boolean ElementIsValid(ElementReference element)
- {
- Boolean isValid = (element != nil && ((**element).structID == kElementRecordID));
-
- Assert(isValid, "ELEMENT ADT: An invalid element has been detected!");
-
- return isValid;
- }
-
-
- /*****************************************************************************
- *
- * ElementIsOrphan PRIVATE
- *
- * Returns true if specified element is not connected to a list
- *
- *****************************************************************************/
- static Boolean ElementIsOrphan(ElementReference element, Boolean warnUser)
- {
- Boolean orphaned;
-
-
- orphaned = false;
-
- if (ElementIsValid(element))
- {
- if ((**element).previous == nil)
- orphaned = true;
-
- if (warnUser)
- {
- Assert(orphaned, "ELEMENT ADT: An invalid orphan has been detected!");
- }
- }
-
- return orphaned;
- }
-
-
- /*****************************************************************************
- *
- * GetLastElementInChain PRIVATE
- *
- * Retrieves the last orphan in an orphan chain.
- *
- *
- * SAMPLE USAGE:
- * ElementReference lastOrphan = GetLastElementInChain(firstOrphan);
- *
- *****************************************************************************/
- static ElementReference GetLastElementInChain(ElementReference firstElement)
- {
- ElementReference lastElement = nil;
-
- if (ElementIsOrphan(firstElement, true))
- {
- lastElement = firstElement;
- while (GetNextElement(lastElement) != nil)
- lastElement = GetNextElement(lastElement);
- }
-
- return lastElement;
- }
-
- // --------------------------------------------------------------------------
-
- #pragma mark -
- #pragma mark ACCESSORS
- #pragma mark -
-
- // --------------------------------------------------------------------------
-
- ElementType GetElementType(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).elementType : kUnknownElement;
- }
-
- // --------------------------------------------------------------------------
-
- unsigned long GetElementNumber(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).elementNumber : -1;
- }
-
-
- // --------------------------------------------------------------------------
-
- ElementList GetElementSubElementList(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).subElementList : nil;
- }
-
-
- // --------------------------------------------------------------------------
-
- Rect GetElementBoundingBox(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).boundingBox : fgEmptyRect;
- }
-
- // --------------------------------------------------------------------------
-
- Point GetElementRoundRectOvalSize(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).roundRectOvalSize : fgEmptyPoint;
- }
-
-
- // --------------------------------------------------------------------------
-
- Point GetElementLineBeginPoint(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).line[0] : fgEmptyPoint;
- }
-
-
- // --------------------------------------------------------------------------
-
- Point GetElementLineEndPoint(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).line[1] : fgEmptyPoint;
- }
-
-
- // --------------------------------------------------------------------------
-
- PolyHandle GetElementPolygon(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).polygon : nil;
- }
-
- // --------------------------------------------------------------------------
-
- RGBColor GetElementFillColor(ElementReference element)
- {
- RGBColor white = kRGBWhite;
-
- return ElementIsValid(element) ? (**element).fillInfo.rgbColor : white;
- }
-
- // --------------------------------------------------------------------------
-
- short GetElementStrokePenWidth(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).strokeInfo.penWidth : 0;
- }
-
- // --------------------------------------------------------------------------
-
- short GetElementStrokePenHeight(ElementReference element)
- {
- return ElementIsValid(element) ? (**element).strokeInfo.penHeight : 0;
- }
-
- // --------------------------------------------------------------------------
-
- RGBColor GetElementStrokeColor(ElementReference element)
- {
- RGBColor black = kRGBBlack;
-
- return ElementIsValid(element) ? (**element).strokeInfo.rgbColor : black;
- }
-
- // --------------------------------------------------------------------------
-
- #pragma mark -
- #pragma mark MANIPULATORS
- #pragma mark -
-
- // --------------------------------------------------------------------------
-
- void SetElementType(ElementReference element, ElementType elementType)
- {
- if (ElementIsValid(element))
- (**element).elementType = elementType;
- }
-
-
- // --------------------------------------------------------------------------
-
- void SetElementBoundingBox(ElementReference element, Rect boundingBox)
- {
- if (ElementIsValid(element))
- {
- (**element).boundingBox = boundingBox;
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementRoundRectOvalSize(ElementReference element, Point ovalSize)
- {
- if (ElementIsValid(element))
- (**element).roundRectOvalSize = ovalSize;
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementLineBeginPoint(ElementReference element, Point p)
- {
- if (ElementIsValid(element))
- (**element).line[0] = p;
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementLineEndPoint(ElementReference element, Point p)
- {
- if (ElementIsValid(element))
- (**element).line[1] = p;
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementPolygon(ElementReference element, PolyHandle polygon)
- {
- if (ElementIsValid(element))
- {
- if ((**element).polygon != polygon)
- if ((**element).polygon)
- KillPoly((**element).polygon);
-
- (**element).polygon = polygon;
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementFillColor(ElementReference element, RGBColor color)
- {
- if (ElementIsValid(element))
- (**element).fillInfo.rgbColor = color;
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementStrokePenWidth(ElementReference element, short penWidth)
- {
- if (ElementIsValid(element))
- {
- (**element).strokeInfo.penWidth = penWidth;
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementStrokePenHeight(ElementReference element, short penHeight)
- {
- if (ElementIsValid(element))
- {
- (**element).strokeInfo.penHeight = penHeight;
- }
- }
-
- // --------------------------------------------------------------------------
-
- void SetElementStrokeColor(ElementReference element, RGBColor color)
- {
- if (ElementIsValid(element))
- (**element).strokeInfo.rgbColor = color;
- }
-
- // --------------------------------------------------------------------------
-
- /*****************************************************************************
- *
- * CloneHandle
- *
- * Allocates a new handle, copies the original handles contents to the new handle
- * and returns. The handle states will also be the same (purgeable, locked, etc).
- * If an error occurs, nil will be returned.
- *
- *****************************************************************************/
-
- static Handle CloneHandle(Handle original)
- {
- Handle duplicate;
- char state;
-
- Assert(original != nil, "invalid handle");
-
- duplicate = original;
- state = HGetState(original);
-
- HandToHand(&duplicate);
-
- if (MemError() == noErr)
- {
- HSetState(original, state); // just to make sure the toolbox didn't screw this up
-
- if (((unsigned short) state) & 0x0080)
- HLock(duplicate);
-
- if (((unsigned short) state) & 0x0040)
- HPurge(duplicate);
- }
- else
- {
- duplicate = nil;
- }
-
- return duplicate;
- }
-
-
-
-
-
-